package com.sky.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageDTO;
import com.sky.entity.Dish;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.exception.BusinessException;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageBean;
import com.sky.service.SetmealService;
import com.sky.vo.DishItemVO;
import com.sky.vo.SetmealVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private SetmealDishMapper setmealDishMapper;

    //套餐分页查询
    @Override
    public PageBean<SetmealVO> findByPage(SetmealPageDTO setmealPageDTO) {
        //1. 开启分页
        PageHelper.startPage(setmealPageDTO.getPage(), setmealPageDTO.getPageSize());
        //2. 执行查询
        List<SetmealVO> list = setmealMapper.findList(setmealPageDTO);
        Page<SetmealVO> page = (Page<SetmealVO>) list;
        //3. 返回结果
        return new PageBean(page.getTotal(), page.getResult());
    }

    //新增套餐
    @Transactional
    @Override
    public void save(SetmealDTO setmealDTO) {
        //1. 从dto中提取套餐基本信息,保存到套餐表中,主键返回
        Setmeal setmeal = BeanUtil.copyProperties(setmealDTO, Setmeal.class);
        setmealMapper.save(setmeal);

        //2. 从dto中提取套餐中的菜品信息,遍历之后设置套餐id, 保存到中间表
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        if (CollUtil.isNotEmpty(setmealDishes)) {
            setmealDishes.stream().forEach(
                    setmealDish -> {
                        //设置套餐id
                        setmealDish.setSetmealId(setmeal.getId());
                        //保存到中间表
                        setmealDishMapper.save(setmealDish);
                    }
            );
        }
    }

    //回显套餐->根据id查询套餐
    @Override
    public SetmealVO findById(Long id) {
        //1.根据套餐id从套餐表中查询信息
        SetmealVO setmealVO = setmealMapper.findById(id);
        //2.根据套餐id从中间查询菜品集合
        List<SetmealDish> list = setmealDishMapper.findBySetmealId(id);
        //3.将list集合直接保存到vo中,
        setmealVO.setSetmealDishes(list);
        return setmealVO;
    }

    //修改套餐
    @Override
    public void update(SetmealDTO setmealDTO) {
        //1. 从dto中提取套餐基本信息,保存到套餐表中,主键返回
        Setmeal setmeal = BeanUtil.copyProperties(setmealDTO, Setmeal.class);
        setmealMapper.update(setmeal);

        //2. 从dto中提取套餐中的菜品信息
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        if (CollectionUtil.isNotEmpty(setmealDishes)) {
            //3. 根据套餐id从中间表删除
            setmealDishMapper.deleteBySetmealId(setmealDTO.getId());

            //4. 重新遍历菜品列表完成添加
            setmealDishes.stream().forEach(setmealDish -> {
                //设置套餐id
                setmealDish.setSetmealId(setmeal.getId());
                //保存到中间表
                setmealDishMapper.save(setmealDish);//复用中间表的保存方法
            });
        }
    }

    //套餐的起售、停售
    @Override
    public void updateStatus(Long id, Integer status) {
        //如果要起售套餐，先判断套餐下是否有未起售的菜品
        if (status == StatusConstant.ENABLE) {
            List<Dish> dishes = setmealDishMapper.findDishesBySetmealId(id);
            for (Dish dish : dishes) {
                if (dish.getStatus() == StatusConstant.DISABLE) {
                    throw new BusinessException(MessageConstant.SETMEAL_ENABLE_FAILED);
                }
            }
        }
        Setmeal setmeal = Setmeal.builder()
                .id(id)
                .status(status)
                .build();
        setmealMapper.update(setmeal);
    }

    //批量删除套餐
    @Override
    @Transactional
    public void deleteByIds(Long[] ids) {
        //判断套餐是否在售
        for (Long id : ids) {
            SetmealVO setmealVO = setmealMapper.findById(id);
            if (setmealVO.getStatus() == StatusConstant.ENABLE) {
                throw new BusinessException(MessageConstant.SETMEAL_ON_SALE);
            }
        }
        //删除套餐
        setmealMapper.deleteByIds(ids);
        //删除套餐的菜品信息
        for (Long id : ids) {
            setmealDishMapper.deleteBySetmealId(id);
        }
    }

    //根据id查询套餐的菜品列表
    @Override
    public List<DishItemVO> findDishList(Long id) {
        return setmealDishMapper.findDishList(id);
    }

    //根据分类id查询套餐列表
    @Override
    public List<SetmealVO> findList(SetmealPageDTO setmealPageDTO) {
        return setmealMapper.findList(setmealPageDTO);
    }

}